#pragma once

using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
using namespace System::Drawing::Design;

#undef GetCurrentDirectory
#include "PropertyManagement/Property.h"
#include "PropertyManagement/NaturalSplinePropertyEditor.h"

namespace SEPEditor {

	/// <summary>
	/// Summary for NaturalSplineEditor
	///
	/// WARNING: If you change the name of this class, you will need to change the
	///          'Resource File Name' property for the managed resource compiler tool
	///          associated with all .resx files this class depends on.  Otherwise,
	///          the designers will not be able to interact properly with localized
	///          resources associated with this form.
	/// </summary>
	public ref class NaturalSplineEditor :public WeifenLuo::WinFormsUI::Docking::DockContent//public System::Windows::Forms::Form
	{
	public:
		void set_pos(const float3& pos)
		{
			this->x->Value=(System::Decimal)pos.x;
			this->y->Value=(System::Decimal)pos.y;
			this->z->Value=(System::Decimal)pos.z;
		}


		void set_selected(int index)
		{
			if (obj->get_selected_index()!=index)
			{
				obj->set_selected_index(index);
				SetTrackbars();
				timeline->Invalidate();
				curvePanel->Invalidate();
			}
		}

		void delete_node(int n)
		{
			obj->remove_node(n);
			timeline->Invalidate();
			curvePanel->Invalidate();
			SetTrackbars();

		}

		void add_node(float t)
		{
			obj->new_node_at_time(t);
			SetTrackbars();
		}

		void set_rot(float3& rot)
		{
			this->yaw->Value=(System::Decimal)rot.x;
			this->pitch->Value=(System::Decimal)rot.y;
			this->roll->Value=(System::Decimal)rot.z;
		}
		NaturalSplinePropertyEditor^ mouseeventhandler;
		NaturalSplineObjectProp^ obj;
//	private: System::Windows::Forms::Panel^  curvePanel;
	private: System::Windows::Forms::ListBox^  trackSelector;
	private: SEPEditor::TransPanel^  curvePanel;
	private: System::Windows::Forms::NumericUpDown^  minPos;
	private: System::Windows::Forms::NumericUpDown^  maxPos;
	public: 
		String^ prop_name;
		NaturalSplineEditor(NaturalSplineObjectProp^ o, String^ property_name)
		{
			prop_name=property_name;
			InitializeComponent();
			//
			//TODO: Add the constructor code here
			//
			obj=o;
			SetTrackbars();
			timeline_length->Value=clamp(int(obj->get_time(obj->get_node_num()-1)+1),(int)timeline_length->Minimum,(int)timeline_length->Maximum);

			mouseeventhandler=gcnew NaturalSplinePropertyEditor();
			mouseeventhandler->editor=this;
			this->Text="Spline Editor - "+gcnew String(o->entity->name.c_str())+" "+property_name;

		}
	protected:
		void SetTrackbars()
		{
			int act=obj->get_selected_index();
			if (act==-1)
				return;
			float3 pos=obj->get_pos(act);
			float3 rot=obj->get_rot(act);
			float t=obj->get_time(act);
			x->Value=(System::Decimal)pos.x;
			y->Value=(System::Decimal)pos.y;
			z->Value=(System::Decimal)pos.z;

			yaw->Value=(System::Decimal)rot.x;
			pitch->Value=(System::Decimal)rot.y;
			roll->Value=(System::Decimal)rot.z;

			time->Value=(System::Decimal)t;

			closed->Checked=obj->is_closed();
			InvalidateRenderViews();
		}

	protected:
		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		~NaturalSplineEditor()
		{
			if (components)
			{
				delete components;
			}
		}
	private: System::Windows::Forms::CheckBox^  closed;
	protected: 
	private: SEPEditor::TransPanel^  timeline;
	private: System::Windows::Forms::Label^  label1;
	private: System::Windows::Forms::Label^  label2;
	private: System::Windows::Forms::Label^  label3;
	private: System::Windows::Forms::Label^  label4;
	private: System::Windows::Forms::Label^  label5;
	private: System::Windows::Forms::Label^  label6;
	private: System::Windows::Forms::Label^  label7;
	private: System::Windows::Forms::Label^  label9;
	private: System::Windows::Forms::Label^  label8;
	private: System::Windows::Forms::NumericUpDown^  x;
	private: System::Windows::Forms::NumericUpDown^  y;
	private: System::Windows::Forms::NumericUpDown^  z;
	private: System::Windows::Forms::NumericUpDown^  yaw;
	private: System::Windows::Forms::NumericUpDown^  pitch;
	private: System::Windows::Forms::NumericUpDown^  roll;
	private: System::Windows::Forms::NumericUpDown^  time;
	private: System::Windows::Forms::NumericUpDown^  timeline_start;
	private: System::Windows::Forms::NumericUpDown^  timeline_length;

	protected: 




















	protected: 


	protected: 






















	private:
		/// <summary>
		/// Required designer variable.
		/// </summary>
		System::ComponentModel::Container ^components;

#pragma region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		void InitializeComponent(void)
		{
			this->closed = (gcnew System::Windows::Forms::CheckBox());
			this->timeline = (gcnew SEPEditor::TransPanel());
			this->label1 = (gcnew System::Windows::Forms::Label());
			this->label2 = (gcnew System::Windows::Forms::Label());
			this->label3 = (gcnew System::Windows::Forms::Label());
			this->label4 = (gcnew System::Windows::Forms::Label());
			this->label5 = (gcnew System::Windows::Forms::Label());
			this->label6 = (gcnew System::Windows::Forms::Label());
			this->label7 = (gcnew System::Windows::Forms::Label());
			this->label9 = (gcnew System::Windows::Forms::Label());
			this->label8 = (gcnew System::Windows::Forms::Label());
			this->x = (gcnew System::Windows::Forms::NumericUpDown());
			this->y = (gcnew System::Windows::Forms::NumericUpDown());
			this->z = (gcnew System::Windows::Forms::NumericUpDown());
			this->yaw = (gcnew System::Windows::Forms::NumericUpDown());
			this->pitch = (gcnew System::Windows::Forms::NumericUpDown());
			this->roll = (gcnew System::Windows::Forms::NumericUpDown());
			this->time = (gcnew System::Windows::Forms::NumericUpDown());
			this->timeline_start = (gcnew System::Windows::Forms::NumericUpDown());
			this->timeline_length = (gcnew System::Windows::Forms::NumericUpDown());
			this->curvePanel = (gcnew SEPEditor::TransPanel());
			this->trackSelector = (gcnew System::Windows::Forms::ListBox());
			this->minPos = (gcnew System::Windows::Forms::NumericUpDown());
			this->maxPos = (gcnew System::Windows::Forms::NumericUpDown());
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->x))->BeginInit();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->y))->BeginInit();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->z))->BeginInit();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->yaw))->BeginInit();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->pitch))->BeginInit();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->roll))->BeginInit();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->time))->BeginInit();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->timeline_start))->BeginInit();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->timeline_length))->BeginInit();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->minPos))->BeginInit();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->maxPos))->BeginInit();
			this->SuspendLayout();
			// 
			// closed
			// 
			this->closed->AutoSize = true;
			this->closed->Location = System::Drawing::Point(943, 20);
			this->closed->Name = L"closed";
			this->closed->Size = System::Drawing::Size(57, 17);
			this->closed->TabIndex = 26;
			this->closed->Text = L"closed";
			this->closed->UseVisualStyleBackColor = true;
			this->closed->CheckedChanged += gcnew System::EventHandler(this, &NaturalSplineEditor::closed_CheckedChanged);
			// 
			// timeline
			// 
			this->timeline->AutoSizeMode = System::Windows::Forms::AutoSizeMode::GrowAndShrink;
			this->timeline->BorderStyle = System::Windows::Forms::BorderStyle::Fixed3D;
			this->timeline->Dock = System::Windows::Forms::DockStyle::Bottom;
			this->timeline->Location = System::Drawing::Point(0, 408);
			this->timeline->Name = L"timeline";
			this->timeline->Size = System::Drawing::Size(1036, 51);
			this->timeline->TabIndex = 7;
			this->timeline->Paint += gcnew System::Windows::Forms::PaintEventHandler(this, &NaturalSplineEditor::timeline_Paint);
			this->timeline->MouseMove += gcnew System::Windows::Forms::MouseEventHandler(this, &NaturalSplineEditor::timeline_MouseMove);
			this->timeline->MouseDown += gcnew System::Windows::Forms::MouseEventHandler(this, &NaturalSplineEditor::timeline_MouseDown);
			// 
			// label1
			// 
			this->label1->AutoSize = true;
			this->label1->Location = System::Drawing::Point(12, 6);
			this->label1->Name = L"label1";
			this->label1->Size = System::Drawing::Size(14, 13);
			this->label1->TabIndex = 13;
			this->label1->Text = L"X";
			// 
			// label2
			// 
			this->label2->AutoSize = true;
			this->label2->Location = System::Drawing::Point(98, 6);
			this->label2->Name = L"label2";
			this->label2->Size = System::Drawing::Size(14, 13);
			this->label2->TabIndex = 12;
			this->label2->Text = L"Y";
			// 
			// label3
			// 
			this->label3->AutoSize = true;
			this->label3->Location = System::Drawing::Point(186, 4);
			this->label3->Name = L"label3";
			this->label3->Size = System::Drawing::Size(14, 13);
			this->label3->TabIndex = 15;
			this->label3->Text = L"Z";
			// 
			// label4
			// 
			this->label4->AutoSize = true;
			this->label4->Location = System::Drawing::Point(289, 6);
			this->label4->Name = L"label4";
			this->label4->Size = System::Drawing::Size(28, 13);
			this->label4->TabIndex = 14;
			this->label4->Text = L"Yaw";
			// 
			// label5
			// 
			this->label5->AutoSize = true;
			this->label5->Location = System::Drawing::Point(399, 4);
			this->label5->Name = L"label5";
			this->label5->Size = System::Drawing::Size(31, 13);
			this->label5->TabIndex = 9;
			this->label5->Text = L"Pitch";
			// 
			// label6
			// 
			this->label6->AutoSize = true;
			this->label6->Location = System::Drawing::Point(528, 6);
			this->label6->Name = L"label6";
			this->label6->Size = System::Drawing::Size(25, 13);
			this->label6->TabIndex = 8;
			this->label6->Text = L"Roll";
			// 
			// label7
			// 
			this->label7->AutoSize = true;
			this->label7->Location = System::Drawing::Point(772, 4);
			this->label7->Name = L"label7";
			this->label7->Size = System::Drawing::Size(75, 13);
			this->label7->TabIndex = 11;
			this->label7->Text = L"TimeLine Start";
			// 
			// label9
			// 
			this->label9->AutoSize = true;
			this->label9->Location = System::Drawing::Point(652, 8);
			this->label9->Name = L"label9";
			this->label9->Size = System::Drawing::Size(14, 13);
			this->label9->TabIndex = 10;
			this->label9->Text = L"T";
			// 
			// label8
			// 
			this->label8->AutoSize = true;
			this->label8->Location = System::Drawing::Point(850, 4);
			this->label8->Name = L"label8";
			this->label8->Size = System::Drawing::Size(86, 13);
			this->label8->TabIndex = 16;
			this->label8->Text = L"TimeLine Length";
			// 
			// x
			// 
			this->x->DecimalPlaces = 1;
			this->x->Increment = System::Decimal(gcnew cli::array< System::Int32 >(4) {1, 0, 0, 65536});
			this->x->Location = System::Drawing::Point(32, 4);
			this->x->Maximum = System::Decimal(gcnew cli::array< System::Int32 >(4) {100000, 0, 0, 0});
			this->x->Minimum = System::Decimal(gcnew cli::array< System::Int32 >(4) {100000, 0, 0, System::Int32::MinValue});
			this->x->Name = L"x";
			this->x->Size = System::Drawing::Size(60, 20);
			this->x->TabIndex = 21;
			this->x->ValueChanged += gcnew System::EventHandler(this, &NaturalSplineEditor::x_ValueChanged);
			// 
			// y
			// 
			this->y->DecimalPlaces = 1;
			this->y->Increment = System::Decimal(gcnew cli::array< System::Int32 >(4) {1, 0, 0, 65536});
			this->y->Location = System::Drawing::Point(118, 4);
			this->y->Maximum = System::Decimal(gcnew cli::array< System::Int32 >(4) {100000, 0, 0, 0});
			this->y->Minimum = System::Decimal(gcnew cli::array< System::Int32 >(4) {100000, 0, 0, System::Int32::MinValue});
			this->y->Name = L"y";
			this->y->Size = System::Drawing::Size(62, 20);
			this->y->TabIndex = 22;
			this->y->ValueChanged += gcnew System::EventHandler(this, &NaturalSplineEditor::y_ValueChanged);
			// 
			// z
			// 
			this->z->DecimalPlaces = 1;
			this->z->Increment = System::Decimal(gcnew cli::array< System::Int32 >(4) {1, 0, 0, 65536});
			this->z->Location = System::Drawing::Point(206, 4);
			this->z->Maximum = System::Decimal(gcnew cli::array< System::Int32 >(4) {100000, 0, 0, 0});
			this->z->Minimum = System::Decimal(gcnew cli::array< System::Int32 >(4) {100000, 0, 0, System::Int32::MinValue});
			this->z->Name = L"z";
			this->z->Size = System::Drawing::Size(65, 20);
			this->z->TabIndex = 23;
			this->z->ValueChanged += gcnew System::EventHandler(this, &NaturalSplineEditor::z_ValueChanged);
			// 
			// yaw
			// 
			this->yaw->Location = System::Drawing::Point(323, 4);
			this->yaw->Maximum = System::Decimal(gcnew cli::array< System::Int32 >(4) {10000, 0, 0, 0});
			this->yaw->Minimum = System::Decimal(gcnew cli::array< System::Int32 >(4) {10000, 0, 0, System::Int32::MinValue});
			this->yaw->Name = L"yaw";
			this->yaw->Size = System::Drawing::Size(70, 20);
			this->yaw->TabIndex = 20;
			this->yaw->ValueChanged += gcnew System::EventHandler(this, &NaturalSplineEditor::yaw_ValueChanged);
			// 
			// pitch
			// 
			this->pitch->Location = System::Drawing::Point(436, 4);
			this->pitch->Maximum = System::Decimal(gcnew cli::array< System::Int32 >(4) {10000, 0, 0, 0});
			this->pitch->Minimum = System::Decimal(gcnew cli::array< System::Int32 >(4) {10000, 0, 0, System::Int32::MinValue});
			this->pitch->Name = L"pitch";
			this->pitch->Size = System::Drawing::Size(86, 20);
			this->pitch->TabIndex = 17;
			this->pitch->ValueChanged += gcnew System::EventHandler(this, &NaturalSplineEditor::pitch_ValueChanged);
			// 
			// roll
			// 
			this->roll->Location = System::Drawing::Point(559, 6);
			this->roll->Maximum = System::Decimal(gcnew cli::array< System::Int32 >(4) {10000, 0, 0, 0});
			this->roll->Minimum = System::Decimal(gcnew cli::array< System::Int32 >(4) {10000, 0, 0, System::Int32::MinValue});
			this->roll->Name = L"roll";
			this->roll->Size = System::Drawing::Size(87, 20);
			this->roll->TabIndex = 18;
			this->roll->ValueChanged += gcnew System::EventHandler(this, &NaturalSplineEditor::roll_ValueChanged);
			// 
			// time
			// 
			this->time->DecimalPlaces = 2;
			this->time->Increment = System::Decimal(gcnew cli::array< System::Int32 >(4) {1, 0, 0, 65536});
			this->time->Location = System::Drawing::Point(672, 6);
			this->time->Maximum = System::Decimal(gcnew cli::array< System::Int32 >(4) {10000, 0, 0, 0});
			this->time->Name = L"time";
			this->time->Size = System::Drawing::Size(82, 20);
			this->time->TabIndex = 19;
			this->time->ValueChanged += gcnew System::EventHandler(this, &NaturalSplineEditor::time_ValueChanged);
			// 
			// timeline_start
			// 
			this->timeline_start->DecimalPlaces = 1;
			this->timeline_start->Increment = System::Decimal(gcnew cli::array< System::Int32 >(4) {1, 0, 0, 65536});
			this->timeline_start->Location = System::Drawing::Point(775, 20);
			this->timeline_start->Maximum = System::Decimal(gcnew cli::array< System::Int32 >(4) {10000, 0, 0, 0});
			this->timeline_start->Name = L"timeline_start";
			this->timeline_start->Size = System::Drawing::Size(72, 20);
			this->timeline_start->TabIndex = 25;
			this->timeline_start->ValueChanged += gcnew System::EventHandler(this, &NaturalSplineEditor::timeline_start_ValueChanged);
			// 
			// timeline_length
			// 
			this->timeline_length->DecimalPlaces = 1;
			this->timeline_length->Location = System::Drawing::Point(853, 20);
			this->timeline_length->Maximum = System::Decimal(gcnew cli::array< System::Int32 >(4) {10000, 0, 0, 0});
			this->timeline_length->Minimum = System::Decimal(gcnew cli::array< System::Int32 >(4) {1, 0, 0, 0});
			this->timeline_length->Name = L"timeline_length";
			this->timeline_length->Size = System::Drawing::Size(64, 20);
			this->timeline_length->TabIndex = 24;
			this->timeline_length->Value = System::Decimal(gcnew cli::array< System::Int32 >(4) {1, 0, 0, 0});
			this->timeline_length->ValueChanged += gcnew System::EventHandler(this, &NaturalSplineEditor::timeline_length_ValueChanged);
			// 
			// curvePanel
			// 
			this->curvePanel->Anchor = static_cast<System::Windows::Forms::AnchorStyles>((((System::Windows::Forms::AnchorStyles::Top | System::Windows::Forms::AnchorStyles::Bottom) 
				| System::Windows::Forms::AnchorStyles::Left) 
				| System::Windows::Forms::AnchorStyles::Right));
			this->curvePanel->BorderStyle = System::Windows::Forms::BorderStyle::Fixed3D;
			this->curvePanel->Location = System::Drawing::Point(0, 94);
			this->curvePanel->Name = L"curvePanel";
			this->curvePanel->Size = System::Drawing::Size(1036, 308);
			this->curvePanel->TabIndex = 27;
			this->curvePanel->Paint += gcnew System::Windows::Forms::PaintEventHandler(this, &NaturalSplineEditor::curvePanel_Paint);
			// 
			// trackSelector
			// 
			this->trackSelector->FormattingEnabled = true;
			this->trackSelector->Items->AddRange(gcnew cli::array< System::Object^  >(7) {L"None", L"X", L"Y", L"Z", L"Yaw", L"Pitch", 
				L"Roll"});
			this->trackSelector->Location = System::Drawing::Point(15, 45);
			this->trackSelector->Name = L"trackSelector";
			this->trackSelector->SelectionMode = System::Windows::Forms::SelectionMode::MultiExtended;
			this->trackSelector->Size = System::Drawing::Size(120, 43);
			this->trackSelector->TabIndex = 28;
			this->trackSelector->SelectedIndexChanged += gcnew System::EventHandler(this, &NaturalSplineEditor::trackSelector_SelectedIndexChanged);
			// 
			// minPos
			// 
			this->minPos->Location = System::Drawing::Point(169, 45);
			this->minPos->Maximum = System::Decimal(gcnew cli::array< System::Int32 >(4) {10000, 0, 0, 0});
			this->minPos->Minimum = System::Decimal(gcnew cli::array< System::Int32 >(4) {10000, 0, 0, System::Int32::MinValue});
			this->minPos->Name = L"minPos";
			this->minPos->Size = System::Drawing::Size(120, 20);
			this->minPos->TabIndex = 29;
			this->minPos->Value = System::Decimal(gcnew cli::array< System::Int32 >(4) {500, 0, 0, System::Int32::MinValue});
			this->minPos->ValueChanged += gcnew System::EventHandler(this, &NaturalSplineEditor::minPos_ValueChanged);
			// 
			// maxPos
			// 
			this->maxPos->Location = System::Drawing::Point(310, 45);
			this->maxPos->Maximum = System::Decimal(gcnew cli::array< System::Int32 >(4) {10000, 0, 0, 0});
			this->maxPos->Minimum = System::Decimal(gcnew cli::array< System::Int32 >(4) {10000, 0, 0, System::Int32::MinValue});
			this->maxPos->Name = L"maxPos";
			this->maxPos->Size = System::Drawing::Size(120, 20);
			this->maxPos->TabIndex = 29;
			this->maxPos->Value = System::Decimal(gcnew cli::array< System::Int32 >(4) {500, 0, 0, 0});
			this->maxPos->ValueChanged += gcnew System::EventHandler(this, &NaturalSplineEditor::maxPos_ValueChanged);
			// 
			// NaturalSplineEditor
			// 
			this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
			this->ClientSize = System::Drawing::Size(1036, 459);
			this->Controls->Add(this->maxPos);
			this->Controls->Add(this->minPos);
			this->Controls->Add(this->trackSelector);
			this->Controls->Add(this->curvePanel);
			this->Controls->Add(this->closed);
			this->Controls->Add(this->timeline_length);
			this->Controls->Add(this->timeline_start);
			this->Controls->Add(this->time);
			this->Controls->Add(this->roll);
			this->Controls->Add(this->pitch);
			this->Controls->Add(this->yaw);
			this->Controls->Add(this->z);
			this->Controls->Add(this->y);
			this->Controls->Add(this->x);
			this->Controls->Add(this->label8);
			this->Controls->Add(this->label9);
			this->Controls->Add(this->label7);
			this->Controls->Add(this->label6);
			this->Controls->Add(this->label5);
			this->Controls->Add(this->label4);
			this->Controls->Add(this->label3);
			this->Controls->Add(this->label2);
			this->Controls->Add(this->label1);
			this->Controls->Add(this->timeline);
			this->DoubleBuffered = true;
			this->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 8.25F, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point, 
				static_cast<System::Byte>(238)));
			this->FormBorderStyle = System::Windows::Forms::FormBorderStyle::SizableToolWindow;
			this->Name = L"NaturalSplineEditor";
			this->Text = L"NaturalSplineEditor";
			this->Shown += gcnew System::EventHandler(this, &NaturalSplineEditor::NaturalSplineEditor_Shown);
			this->Enter += gcnew System::EventHandler(this, &NaturalSplineEditor::NaturalSplineEditor_Enter);
			this->FormClosing += gcnew System::Windows::Forms::FormClosingEventHandler(this, &NaturalSplineEditor::NaturalSplineEditor_FormClosing);
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->x))->EndInit();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->y))->EndInit();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->z))->EndInit();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->yaw))->EndInit();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->pitch))->EndInit();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->roll))->EndInit();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->time))->EndInit();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->timeline_start))->EndInit();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->timeline_length))->EndInit();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->minPos))->EndInit();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->maxPos))->EndInit();
			this->ResumeLayout(false);
			this->PerformLayout();

		}
#pragma endregion
	private: System::Void timeline_Paint(System::Object^  sender, System::Windows::Forms::PaintEventArgs^  e) {
				 System::Drawing::Graphics^ gr=e->Graphics;
				 System::Drawing::Pen^ blackpen=gcnew System::Drawing::Pen(System::Drawing::Color::Black);
				 System::Drawing::SolidBrush^ blackbrush=gcnew System::Drawing::SolidBrush(System::Drawing::Color::Black);
				 System::Drawing::SolidBrush^ redbrush=gcnew System::Drawing::SolidBrush(System::Drawing::Color::Red);

				 int w=timeline->Width;
				 int h=timeline->Height;

				 gr->Clear(timeline->BackColor);

				 gr->DrawLine(blackpen,0,h/2,w,h/2);

				 float starttime=(float)timeline_start->Value;
				 float maxtime=starttime+(float)timeline_length->Value;
				 float tlength=maxtime-starttime;
//				 float rectsize=w/(6*tlength);
				 float rectsize=(float)w/250;

				 for (int n=0; n<obj->get_node_num(); ++n)
				 {
					 float x=((obj->get_time(n)-starttime)/tlength)*(w-2*rectsize);
					 float fh=(float)h;

					 if (n==obj->get_selected_index())
						 gr->FillRectangle(redbrush,x,0.0f,2*rectsize,fh);
					 else
						 gr->FillRectangle(blackbrush,x,0.0f,2*rectsize,fh);
				 }

				 delete blackpen;
				 delete redbrush;
				 delete blackbrush;
//				 delete gr;
			 }
private: System::Void x_ValueChanged(System::Object^  sender, System::EventArgs^  e) {
			 float3 p=obj->get_pos(obj->get_selected_index());
			 p.x=(float)x->Value;
			 obj->set_pos(obj->get_selected_index(),p);
			 curvePanel->Invalidate();
			 InvalidateRenderViews();
		 }
private: System::Void y_ValueChanged(System::Object^  sender, System::EventArgs^  e) {
			 float3 p=obj->get_pos(obj->get_selected_index());
			 p.y=(float)y->Value;
			 obj->set_pos(obj->get_selected_index(),p);
			 curvePanel->Invalidate();
			 InvalidateRenderViews();
		 }
private: System::Void z_ValueChanged(System::Object^  sender, System::EventArgs^  e) {
			 float3 p=obj->get_pos(obj->get_selected_index());
			 p.z=(float)z->Value;
			 obj->set_pos(obj->get_selected_index(),p);
			 curvePanel->Invalidate();
			 InvalidateRenderViews();
		 }
private: System::Void yaw_ValueChanged(System::Object^  sender, System::EventArgs^  e) {
			 float3 r=obj->get_rot(obj->get_selected_index());
			 r.x=(float)yaw->Value;
			 obj->set_rot(obj->get_selected_index(),r);
			 curvePanel->Invalidate();
			 InvalidateRenderViews();
		 }
private: System::Void pitch_ValueChanged(System::Object^  sender, System::EventArgs^  e) {
			 float3 r=obj->get_rot(obj->get_selected_index());
			 r.y=(float)pitch->Value;
			 obj->set_rot(obj->get_selected_index(),r);
			 curvePanel->Invalidate();
			 InvalidateRenderViews();
		 }
private: System::Void roll_ValueChanged(System::Object^  sender, System::EventArgs^  e) {
			 float3 r=obj->get_rot(obj->get_selected_index());
			 r.z=(float)roll->Value;
			 obj->set_rot(obj->get_selected_index(),r);
			 curvePanel->Invalidate();
			 InvalidateRenderViews();
		 }
private: System::Void time_ValueChanged(System::Object^  sender, System::EventArgs^  e) {
			 float t=obj->get_time(obj->get_selected_index());
			 t=(float)time->Value;
			 obj->set_time(obj->get_selected_index(),t);
			 timeline->Invalidate();
			 curvePanel->Invalidate();
			 InvalidateRenderViews();
		 }
private: System::Void timeline_start_ValueChanged(System::Object^  sender, System::EventArgs^  e) {
			 timeline->Invalidate();
			 curvePanel->Invalidate();
			 InvalidateRenderViews();
		 }
private: System::Void timeline_length_ValueChanged(System::Object^  sender, System::EventArgs^  e) {
			 timeline->Invalidate();
			 curvePanel->Invalidate();
			 InvalidateRenderViews();
		 }
private: System::Void closed_CheckedChanged(System::Object^  sender, System::EventArgs^  e) {
			 if (obj->is_closed()!=closed->Checked)
				 obj->set_closed(!obj->is_closed());
		 }
private: System::Void timeline_MouseDown(System::Object^  sender, System::Windows::Forms::MouseEventArgs^  e) {
			 timeline->Focus();
			 int node_num=obj->get_node_num();
			 if (e->Button==System::Windows::Forms::MouseButtons::Right && node_num==2)
				 return;

			 mx=e->X;
			 my=e->Y;
			 int mousex=e->X;
			 int mousey=e->Y;
			 int w=timeline->Width;
			 int h=timeline->Height;


			 float starttime=(float)timeline_start->Value;
			 float maxtime=starttime+(float)timeline_length->Value;
			 float tlength=maxtime-starttime;
//			 float rectsize=w/(6*tlength);
			 float rectsize=(float)w/250;
			 float t=(mousex-rectsize)*tlength/(w-2*rectsize)+starttime;
			 for (int n=0;n<node_num; ++n)
			 {
				 int x=int(((obj->get_time(n)-starttime)/tlength)*(w-2*rectsize)+rectsize);

				 if (abs(x-mousex)<rectsize)
				 {
					 if (e->Button==System::Windows::Forms::MouseButtons::Left || e->Button==System::Windows::Forms::MouseButtons::Middle)
					 {
						 if (obj->get_selected_index()!=n)
						 {
							 obj->set_selected_index(n);
							 SetTrackbars();
							 timeline->Invalidate();
							 curvePanel->Invalidate();
						 }

						 return;

					 }
					 else if (e->Button==System::Windows::Forms::MouseButtons::Right)
					 {
						 if (n)
							 if (MessageBox::Show(
								 "Spline node will be deleted!", 
								 "Leo Designer", MessageBoxButtons::YesNo, 
								 MessageBoxIcon::Exclamation)==System::Windows::Forms::DialogResult::Yes)
						 {
							 if (obj->get_selected_index()!=n)
								 obj->set_selected_index(n);
							 obj->remove_node(n);
							 timeline->Invalidate();
							 curvePanel->Invalidate();
							 SetTrackbars();
						 }
						 return;
					 }
				 }
			 }

			 if (e->Button==System::Windows::Forms::MouseButtons::Left)
			 {
				 obj->new_node_at_time(t);
				 SetTrackbars();
				 return;
			 }

		 }
private: System::Void timeline_MouseMove(System::Object^  sender, System::Windows::Forms::MouseEventArgs^  e) {
			 int act_node=obj->get_selected_index();
			 if (e->Button==System::Windows::Forms::MouseButtons::Middle)
			 {
				 int mousex=e->X;
				 int mousey=e->Y;
				 int w=timeline->Width;
				 int h=timeline->Height;


				 float starttime=(float)timeline_start->Value;
				 float maxtime=starttime+(float)timeline_length->Value;
				 float tlength=maxtime-starttime;
//				 float rectsize=w/(6*tlength);
				 float rectsize=(float)w/250;
				 float t=(mousex-rectsize)*tlength/(w-2*rectsize)+starttime;

				 if (act_node>0 && obj->get_time(act_node-1)+0.1f>t)
					 t=obj->get_time(act_node-1)+0.1f;
				 if (act_node<obj->get_node_num()-1 && obj->get_time(act_node+1)-0.1f<t)
					 t=obj->get_time(act_node+1)-0.1f;

				 if (t<0)
					 t=0;

				 if (Control::ModifierKeys==Keys::Control)
				 {
						float dt=t-obj->get_time(act_node);

						for (int n=act_node; n<obj->get_node_num(); ++n)
							obj->set_time(n,obj->get_time(n)+dt);
				 }
				 else if (Control::ModifierKeys==Keys::Shift)
				 {
					 float mul=1;
					 float r=(e->X-mx)*0.01f;
					 if (r>0)
						 mul=1+mul*r;
					 else
						 mul=1/(1-mul*r);

					 float act_node_time=obj->get_time(act_node);
					 for (int n=act_node+1; n<obj->get_node_num(); ++n)
						 obj->set_time(n,(obj->get_time(n)-act_node_time)*mul+act_node_time);

					 t=obj->get_time(act_node);

				 }
				 else
				 {
					 if (act_node!=0)
						obj->set_time(act_node,t);
				 }

				 timeline->Invalidate();
				 curvePanel->Invalidate();
				 time->Value=(System::Decimal)t;
			 }

			 mx=e->X;
			 my=e->Y;
		 }

		 int mx;
		 int my;
private: System::Void NaturalSplineEditor_Shown(System::Object^  sender, System::EventArgs^  e);
private: System::Void NaturalSplineEditor_FormClosing(System::Object^  sender, System::Windows::Forms::FormClosingEventArgs^  e);
private: System::Void trackSelector_SelectedIndexChanged(System::Object^  sender, System::EventArgs^  e) {
			 if (trackSelector->SelectedIndex==0)
			 {
				 curvePanel->Visible=false;
			 }
			 else
			 {
				 curvePanel->Visible=true;
				 curvePanel->Invalidate();
			 }
		 }
private: System::Void curvePanel_Paint(System::Object^  sender, System::Windows::Forms::PaintEventArgs^  e) {
			 if (!curvePanel->Visible)
				 return;

			 if (trackSelector->SelectedIndex<1)
				 return;

			 System::Drawing::Graphics^ gr=e->Graphics;
			 System::Drawing::Pen^ blackpen=gcnew System::Drawing::Pen(System::Drawing::Color::Black);
			 System::Drawing::SolidBrush^ blackbrush=gcnew System::Drawing::SolidBrush(System::Drawing::Color::Black);
			 System::Drawing::SolidBrush^ redbrush=gcnew System::Drawing::SolidBrush(System::Drawing::Color::Red);

			 int w=curvePanel->Width;
			 int h=curvePanel->Height;

			 gr->Clear(curvePanel->BackColor);

			 int nulla=(int)(h-(-(float)minPos->Value)/((float)(maxPos->Value)-(float)(minPos->Value))*h);
			 gr->DrawLine(blackpen,0,nulla,w,nulla);

			 float starttime=(float)timeline_start->Value;
			 float maxtime=starttime+(float)timeline_length->Value;
			 float tlength=maxtime-starttime;
			 //				 float rectsize=w/(6*tlength);
			 float step=(maxtime-starttime)/500;


			 for (int n=0; n<obj->get_node_num(); ++n)
			 {
				 float x=((obj->get_time(n)-starttime)/tlength)*(w);
				 float fh=(float)h;

				 if (x<0 || x>w)
					 continue;


				gr->DrawLine(blackpen,x,0.0f,x,fh);
			 }


			 for (int fukker=1; fukker<=6; ++fukker)
			 {
				 if (!trackSelector->SelectedIndices->Contains(fukker))
					 continue;
				 for (float f=starttime; f<=maxtime;f+=step)
				 {
					 float s,e;
					 float3 spos=obj->get_pos(f);
					 float3 srot=obj->get_rot(f);
					 float3 epos=obj->get_pos(f+step);
					 float3 erot=obj->get_rot(f+step);

					 switch (fukker)//trackSelector->SelectedIndex)
					 {
					 case 1:
						 {
							s=spos.x;
							e=epos.x;
							break;
						 }
					 case 2:
						 {
							 s=spos.y;
							 e=epos.y;
							 break;
						 }
					 case 3:
						 {
							 s=spos.z;
							 e=epos.z;
							 break;
						 }
					 case 4:
						 {
							 s=srot.x;
							 e=erot.x;
							 break;
						 }
					 case 5:
						 {
							 s=srot.y;
							 e=erot.y;
							 break;
						 }
					 case 6:
						 {
							 s=srot.z;
							 e=erot.z;
							 break;
						 }
					 }

					 int sx=int((f-starttime)/tlength*w);
					 int ex=int((f+step-starttime)/tlength*w);

					 int sy=(int)(h-(s-(float)minPos->Value)/((float)(maxPos->Value)-(float)(minPos->Value))*h);
					 int ey=(int)(h-(e-(float)minPos->Value)/((float)(maxPos->Value)-(float)(minPos->Value))*h);
					 gr->DrawLine(blackpen,sx,sy,ex,ey);

				 }
			 }


			 delete blackpen;
			 delete redbrush;
			 delete blackbrush;
//			 delete gr;
		 }
private: System::Void maxPos_ValueChanged(System::Object^  sender, System::EventArgs^  e) {
			 curvePanel->Invalidate();
		 }
private: System::Void minPos_ValueChanged(System::Object^  sender, System::EventArgs^  e) {
			 curvePanel->Invalidate();
		 }
private: System::Void NaturalSplineEditor_Enter(System::Object^  sender, System::EventArgs^  e);
private: System::Void InvalidateRenderViews();
};






	public ref class UINaturalSplineEditor : public System::Drawing::Design::UITypeEditor
	{
	public:
		virtual UITypeEditorEditStyle GetEditStyle(
			ITypeDescriptorContext^ context) override 
		{
			if (context != nullptr)
				return UITypeEditorEditStyle::Modal;

			return UITypeEditorEditStyle::None;
		}
	public: 
		[RefreshProperties(RefreshProperties::All)]
		virtual System::Object^ EditValue(ITypeDescriptorContext^ context,
			System::IServiceProvider^ provider, System::Object^ value) override ;
	};

	public ref class UISphereArrayEditor: public System::Drawing::Design::UITypeEditor
	{
	public:
		virtual UITypeEditorEditStyle GetEditStyle(
			ITypeDescriptorContext^ context) override 
		{
			if (context != nullptr)
				return UITypeEditorEditStyle::Modal;

			return UITypeEditorEditStyle::None;
		}
	public: 
		[RefreshProperties(RefreshProperties::All)]
		virtual System::Object^ EditValue(ITypeDescriptorContext^ context,
			System::IServiceProvider^ provider, System::Object^ value) override ;
	};
}
